#include "NetworkManager.h"
#include <QNetworkReply>
#include <QTimer>
#include <QDebug>

NetworkManager::NetworkManager(QObject* parent)
    : QObject(parent)
    , m_networkManager(new QNetworkAccessManager(this))
    , m_serverUrl("http://localhost:8080")
    , m_timeout(30000)
    , m_maxConcurrent(5)
    , m_currentTaskId(0) {

    connect(m_networkManager, &QNetworkAccessManager::finished,
            this, &NetworkManager::onRequestFinished);
}

NetworkManager::~NetworkManager() {
    cancelAllTasks();
}

void NetworkManager::setServerUrl(const QString& url) {
        m_serverUrl = url;

}

void NetworkManager::setTimeout(int milliseconds) {
    m_timeout = milliseconds;
}

void NetworkManager::setMaxConcurrentRequests(int maxCount) {
    m_maxConcurrent = qMax(1, maxCount);
}

void NetworkManager::cancelTask(int taskId) {
    QMutexLocker locker(&m_mutex);

    if (m_runningTasks.contains(taskId)) {
        NetworkTask* task = m_runningTasks.value(taskId);
        if (task->getNetworkReply()) {
            task->getNetworkReply()->abort();
        }
        cleanupTask(taskId);
    } else {
        // 从队列中移除
        for (auto it = m_taskQueue.begin(); it != m_taskQueue.end(); ++it) {
            if ((*it)->getTaskId() == taskId) {
                delete *it;
                m_taskQueue.erase(it);
                break;
            }
        }
    }
}

void NetworkManager::cancelAllTasks() {
    QMutexLocker locker(&m_mutex);

    // 取消所有运行中的任务
    for (int taskId : m_runningTasks.keys()) {
        NetworkTask* task = m_runningTasks.value(taskId);
        if (task->getNetworkReply()) {
            task->getNetworkReply()->abort();
        }
        cleanupTask(taskId);
    }

    // 清空队列
    while (!m_taskQueue.isEmpty()) {
        delete m_taskQueue.dequeue();
    }
}

void NetworkManager::onRequestFinished(QNetworkReply* reply) {
    QMutexLocker locker(&m_mutex);

    if (!m_replyToTaskMap.contains(reply)) {
        reply->deleteLater();
        return;
    }

    int taskId = m_replyToTaskMap.value(reply);
    m_replyToTaskMap.remove(reply);

    if (!m_runningTasks.contains(taskId)) {
        reply->deleteLater();
        return;
    }

    NetworkTask* task = m_runningTasks.value(taskId);
    task->setNetworkReply(nullptr);

    // 停止超时计时器
    if (m_taskTimers.contains(taskId)) {
        m_taskTimers.value(taskId)->stop();
        delete m_taskTimers.value(taskId);
        m_taskTimers.remove(taskId);
    }

    bool success = false;
    QString errorString;

    if (reply->error() == QNetworkReply::NoError) {
        QByteArray responseData = reply->readAll();
        success = task->getResponse()->fromJson(responseData);
        if (!success) {
            errorString = "Response data parsing failed";
        }
    } else {
        errorString = reply->errorString();
        emit networkError(taskId, errorString);
    }

    emit requestCompleted(taskId, success, errorString);

    // 清理任务
    cleanupTask(taskId);
    reply->deleteLater();

    // 处理下一个任务
    processNextTask();
}

void NetworkManager::onRequestTimeout() {
    QMutexLocker locker(&m_mutex);

    QTimer* timer = qobject_cast<QTimer*>(sender());
    if (!timer) return;

    int taskId = timer->property("taskId").toInt();
    if (!m_runningTasks.contains(taskId)) return;

    NetworkTask* task = m_runningTasks.value(taskId);
    if (task->getNetworkReply()) {
        task->getNetworkReply()->abort();
    }

    emit networkError(taskId, "Request timeout");
    cleanupTask(taskId);

    // 处理下一个任务
    processNextTask();
}

void NetworkManager::processNextTask() {
    QMutexLocker locker(&m_mutex);

    if (m_taskQueue.isEmpty() || m_runningTasks.size() >= m_maxConcurrent) {
        return;
    }

    NetworkTask* task = m_taskQueue.dequeue();
    m_runningTasks.insert(task->getTaskId(), task);

    sendHttpPost(task);
}

void NetworkManager::sendHttpPost(NetworkTask* task) {
    QNetworkRequest request;
    QString url = m_serverUrl + task->getRequest()->getEndPoint();
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QByteArray requestData = task->getRequest()->toJson();
    QNetworkReply* reply = m_networkManager->post(request, requestData);
    task->setNetworkReply(reply);
    m_replyToTaskMap.insert(reply, task->getTaskId());

    // 设置超时计时器
    QTimer* timer = new QTimer(this);
    timer->setSingleShot(true);
    timer->setProperty("taskId", task->getTaskId());
    connect(timer, &QTimer::timeout, this, &NetworkManager::onRequestTimeout);
    timer->start(m_timeout);
    m_taskTimers.insert(task->getTaskId(), timer);
}

int NetworkManager::generateTaskId() {
    return ++m_currentTaskId;
}

void NetworkManager::cleanupTask(int taskId) {
    if (m_runningTasks.contains(taskId)) {
        NetworkTask* task = m_runningTasks.value(taskId);
        m_runningTasks.remove(taskId);
        delete task;
    }

    if (m_taskTimers.contains(taskId)) {
        QTimer* timer = m_taskTimers.value(taskId);
        m_taskTimers.remove(taskId);
        delete timer;
    }
}
